Maintaining causality between design regularities and source code

نویسنده

  • Andy Kellens
چکیده

ion level in the implementation Another property of structural source-code regularities is that they are generally prevalent at a particular abstraction level in the implementation. Similar to the work of Buschmann et al. [BMR+96] on pattern-oriented software architecture, we distinguish between three abstraction levels which regularities can occur at: 2.1. STRUCTURAL SOURCE-CODE REGULARITIES 15 • architectural level: regularities which express how the different subsystems of a system are related or may interact. One example of such a regularity is that of a layered architecture, in which an entity X in one layer can only communicate with an entity Y if Y is in a layer directly above or below the layer of X; • design level: regularities which encode how the different entities within a subsystem should interact. Typical examples of such regularities are the different conventions and dependencies underlying the implementation of design patterns; • language level: low-level regularities expressing a regularity in a particular part of a subsystem. Examples of these regularities are programming idioms such as the correct use of a double dispatch protocol, accessors for fields, . . . While the above abstraction levels are often associated with other software artifacts such as for instance UML diagrams which express the design of a system or the description of the architecture of a system using an architectural description language, we restrict ourselves solely to the source code of a system. As such, the abstraction level of a structural sourcecode regularity expresses the level of abstraction at which a regularity manifests itself in the source code of a system. Although it might seem at first sight that the scope of a regularity and its abstraction-level are correlated, this is not always the case. While regularities at the architectural level tend to be global, this does not imply that structural regularities at the language level are local. For instance, naming conventions, which are typically found at the language level, can describe a constraint which is globally applicable as well as dictate how program entities in a specific class hierarchy should be named. Similarly, regularities expressing the use of programming idioms can govern a global property (e.g. all field accesses must happen using a getter method) as well as specify the usage of a specific instantiation of an idiom (e.g. all “accept methods” in an instantiation of the Visitor design pattern [GHJV95] must be implemented by a double dispatch protocol). Applicability of structural source-code regularities Structural source-code regularities can be characterized according to their applicability. While certain regularities are quite universal and can be applied to almost any software system, there also exist regularities the applicability of which is limited to a given development team or one specific application or domain. • Environment-specific regularities: group constraints which are applicable to a wide range of software systems, independent of a single development team or the application-domain of the system. They generally encode knowledge concerning frequently occurring errors, language idioms, and so on. While they are not always applicable, their applicability is generally restricted to a certain implementation language, programming paradigm or implementation platform; • Team-specific regularities: these regularities express the coding conventions and naming conventions used by a specific developer or team of developers; 16 CHAPTER 2. STRUCTURAL SOURCE-CODE REGULARITIES • Application-specific regularities: describe the dependencies, conventions, inheritance constraints, . . . typical for a singular system or a particular application domain. Such regularities describe the constraints which must be adhered to when implementing an application-specific or domain-specific concern in a certain software system. For instance, a set of regularities which express that in a graphical framework the actions for drawing figures need to be implemented by means of the Command design pattern, are considered to be application-specific regularities. Note that the applicability of a regularity is strongly correlated with how often it is reused throughout different software projects. Environment-specific regularities often only depend on the implementation language used in a project or the platform which the application must run on. Therefore, throughout numerous projects, often the same set of structural source-code regularities will occur. Team-specific regularities represent the coding style and good practice patterns a team of software developers should adhere to. As such, they too are often reusable over multiple projects. Structural source-code regularities which dictate how certain concerns in a specific application should be structured or how they relate, encode knowledge which usually is not portable to other projects. Note however that even application-specific regularities often share large similarities throughout different software systems. Although the same instance of a regularity is not applicable to two software systems, these similarities between structural source-code regularities can lie at the basis of a kind of “pattern language” which describes how certain types of regularities can be documented. 2.1.3 Taxonomy of structural source-code regularities based on functionality The properties of structural source-code regularities we discussed in the section above provide a characterization of the different kinds of regularities. In this section we discuss a taxonomy of structural source-code regularities found in literature based on the function the regularities serve in the development process. This taxonomy was presented by Chowdhurry et al. [CM93] and was later also adopted by Bokowski [Bok99]. Although in their work they use the term constraints over source code, this taxonomy is equally applicable to structural source-code regularities. This taxonomy divides regularities into three categories: stylistic regularities, implementation regularities and design-level regularities: • stylistic regularities: this category encompasses all regularities which are concerned with the use of names in the system or any other constraint that is semantics-neutral and governs a syntactical property of the source code. Such regularities are used to make programs more readable by enforcing a uniform look and coding style; • implementation regularities: this category consists of regularities which are used to detect infractions against frequently occurring bugs, pitfalls and programming errors. For instance, the regularity that all classes in Smalltalk which implement the = operation must also understand a message hash, is an implementation regularity. Other examples of implementation regularities are for instance the constraints which must be adhered to for an application to run in a specific environment; 2.1. STRUCTURAL SOURCE-CODE REGULARITIES 17 • design-level regularities: rules governing the correct use of class hierarchies, components, frameworks, design patterns, . . . Design-level regularities are further subdivided into coding conventions, inheritance constraints and usage constraints: • coding conventions: regularities which structurally ease readability and maintainability of the source code. For instance, a possible coding convention in Smalltalk is that all accesses to instance variables must occur via a getter method; • inheritance constraints: these regularities express contracts between a class and its subclasses. E.g. a constraint like “all subclasses of ClassA must override a method methodA”; • usage constraints: such regularities express how certain classes or collections of classes are to be used. E.g. in an instantiation of the Factory design pattern [GHJV95] all clients must use the factory to create a product. 2.1.4 Importance of regularities in the software development process In his seminal paper “No silver bullet” [Bro87], Brooks states that software development is inherently hard due to the complex nature of software systems and the lack of unified engineering principles which are prevalent throughout other engineering disciplines. As Minsky observed [Min96], the proper and meticulous use of regularities in software systems can be considered as a kind of engineering principle which aids in dealing with the complexity of software engineering. Regularities can be considered to be a kind of pattern which is present in the source code of a system and which describes how a certain concept, functionality or concern in the system is represented in the source code. One motivation for introducing such regularities in the source code is to improve the communication of the intention of one developer to another. Rigorous use of naming conventions and other stylistic regularities to create a uniform coding style makes the source code of the system more readable [Bec97]. When a certain concern is characterized by a number of regularities, and these regularities are upheld throughout the implementation of the concern, it becomes easier for a developer to identify and understand the implementation of the concern in the source code. However, as we discussed earlier, not all regularities are stylistic in nature. During the development of a software system, certain constraints, or regularities, must be upheld in order for the system to behave properly. Especially in libraries, frameworks, . . . it is imperative that certain regularities are not violated in order for the system not to show incorrect behavior [Bok99, Min91]. For instance, in a framework, certain usage constraints and inheritance regularities govern the correct instantiation of the framework. If these regularities are not upheld, an instantiation of the framework might behave erratically. Similarly, certain development platforms like J2EE impose different regularities to be respected in software systems in order to prevent erratic behavior at runtime [EMS+04]. With the advent of aspect-oriented software development, this need for consistent use of regularities becomes even more important. Due to the nature of the quantification mechanisms 18 CHAPTER 2. STRUCTURAL SOURCE-CODE REGULARITIES employed by pointcut languages, developers of aspect-oriented programs often rely on the fact that certain concepts in the system are characterized by stylistic or structural constraints. For instance, an aspect developer who wishes to capture the concept of a getter-method might assume that all getter-methods are implemented by the Java convention in which the name of the method starts with the prefix get-. In such cases, the proper functioning of the application relies on this naming convention. If a developer does not respect such a stylistic regularity, this can have an impact on the software behaving correctly. This fragility of aspect-oriented programs with respect to seemingly safe modifications of the base program has been dubbed the fragile pointcut problem [KS04, SG05, KMBG06]. 2.1.5 Supporting structural source-code regularities during software development A major drawback of regularities is that they are not an integral part of the programming language. Although programming languages impose a number of constraints on programs by means of syntax and semantics, the majority of regularities are only implicitly present in the implementation. While structural source-code regularities can appear in the source code in an ad-hoc way, i.e. developers unknowingly introduce them as a means to make their source code more readable, often teams of developers regulate the use of certain conventions and constraints which need to be upheld in the implementation. However, due to their crosscutting nature and the fact that development environments typically do not provide support for documenting and enforcing them, over time the consistency and coherent use of structural source-code regularities can diminish. Changes in the source code can result in the regularity no longer being respected. This can lead to source code becoming more difficult to read and bugs being introduced if the violated regularities have an impact on the correct functioning of the system. It is thus important that correct and meticulous use of structural source-code regularities is supported during the development of the system. An approach for maintaining the causal connection between regularities and source code must support the following functionality: • Explicit documentation: A key part of supporting structural source-code regularities lies in their being explicitly documented. This documentation makes it possible to make the implicitly-available regularities in the source code explicit to developers and turns the regularities into first-class artifacts in the development process. This explicit documentation serves as a means to communicate the different structural source-code regularities underlying a system between different developers; • Verification of regularities: Although documenting the regularities aids in making developers aware of their existence, this alone does not suffice to ensure that the regularities are properly adhered to throughout the implementation. In addition, support is needed to verify the validity of the implementation of a system with respect to structural source-code regularities. For an approach to be able to support the verification of regularities imposes a number of requirements: 2.1. STRUCTURAL SOURCE-CODE REGULARITIES 19 – Connection with source code: A causal link must exist between the documentation of regularities and the implementation. Documentation must be expressed in terms of actual source-code entities like classes, methods, fields, and so on. If such a link does not exist between the documentation and the source code, it is not possible to verify the consistency of the documentation with respect to the source code; – Verifiability: Since the documentation of regularities needs to be verifiable, a natural language description of the regularities does not suffice. What’s more, the medium used to express the regularities must be rich enough to capture a wide range of regularities. Preferably, the same approach can be used to capture naming conventions and coding conventions as well as programming idioms, architectural regularities, design dependencies, . . . ; • Support for co-design and co-evolution: The terms co-design and coevolution [DDMW00] has been used in literature to indicate the situation in which a number of (software) artifacts coexist that are causally linked and in which changes to one of the artifacts have as a direct result that the other artifacts might need to be updated as well in order to keep all of the artifacts synchronized. In other words, the development and evolution of any particular artifact cannot be considered in isolation from the other artifacts. In the case of supporting structural source-code regularities during the development process, we encounter a similar situation. The regularities that govern the implementation of a system are causally linked to the source code of that system. While the regularities express how certain concepts in the source code are supposed to be structured, the source code contains the actual manifestation of these regularities. Consequently, this causal link must be maintained during the development of the system. First of all, the documentation and verification of the regularities must not be limited to a single version of the system. During evolution, it must remain possible to verify the validity of the documentation of the structural source-code regularities with respect to the new implementation of the system. In other words, it must be possible to verify whether or not the source-code entities that where added or modified during the evolution step respect the documented regularities. Conversely, not only the implementation of the system evolves over time. As we have mentioned earlier, changes in the requirements, execution environment, design, conventions and so on can have as consequence that the structural source-code regularities that govern a system are altered. As such, an approach for supporting structural sourcecode regularities must be able to deal with evolving regularities as well. In order to deal with this interplay between the documentation of structural source-code regularities on the one hand and the implementation of a system on the other hand, an approach must thus provide support for co-design and co-evolution between the two. 20 CHAPTER 2. STRUCTURAL SOURCE-CODE REGULARITIES 2.2 Software classifications One of the cornerstones of our approach is the use of a software classification mechanism in order to group a set of conceptually related source-code entities which are characterized by a number of structural source-code regularities. The idea of using a classification mechanism to model groups of related entities is certainly not novel. In literature, various approaches exist which employ classifications in order to document different types of concerns in source code. In the following sections we give an overview of some of the software classification models that have been proposed in literature. In Chapter 4, we will revisit these classification models and provide a comparison with the classification model we use in the approach we advance in this dissertation. 2.2.1 (Virtual) software classifications In his PhD dissertation [DH98], Koen De Hondt introduced the notion of software classifications as a means to create online documentation of software artifacts in order to provide support for software evolution. Software classifications provide a lightweight and conceptually simple approach: a software classification is defined as a collection of software entities. For instance, applied to an object-oriented programming language, a software classification can contain a number of classes, fields, methods, and so on. In De Hondt’s work, these software classifications are used to capture the extent of important concerns in the source code. For a developer who needs to change the software, these classifications can be used as a means to browse the implementation of a concern that needs to be altered. The classifications in De Hondt’s work can be specified in two ways. A first way is by explicitly enumerating software artifacts belonging to the classification. For the second way, De Hondt introduced the notion of a virtual software classification. A user does not enumerate the artifacts belonging to the classification in order to define this kind of classification, but rather provides an executable description (i.e. a query over the source code). Upon execution of this description, the elements belonging to the virtual software classification are calculated. Wuyts provided tool support for this classification model of De Hondt by means of the StarBrowser [Wuy02, WD04]. StarBrowser is an extension to the Cincom VisualWorks Smalltalk environment and enables the classification of Smalltalk objects. These classifications can be created either by manually dragging and dropping elements into a classification, or by means of a specification written using a Smalltalk program or a SOUL [Wuy01] logic query. Kim Mens extended the concept of virtual software classification in his PhD thesis [Men00], in which classifications lie at the heart of an approach to co-evolve an architectural description with the source code of a system using logic meta programming. Mens’s approach differentiates between an architectural description language and an architectural mapping language. The description language describes the high-level concepts which make up the architecture of the system and the relations between these concepts. In order to specify the concepts in the architecture, constructs for ports, filters and links are also provided. In the architectural mapping language, virtual software classifications are created which relate the concepts from the architectural description to the implementation of the system and which 2.2. SOFTWARE CLASSIFICATIONS 21 allow keeping this architectural description synchronized with the source code of the system. 2.2.2 Concern Manipulation Environment The Concern Manipulation Environment (CME) [HOST05a, HOST05b, CHK+05, TCH+04] is a tool suite implemented as part of the Eclipse [IBM] development environment. The goal of the CME is to provide an environment for supporting aspect-oriented software development [KLM+97]. In CME, concerns are treated as first-class entities and are accessible throughout the entire software development cycle. The ConMan [HOST05a] component of the CME offers a classification model bearing similarities to the classification models discussed above. While in our work we will focus on the classification of source-code entities, the CME approach takes a broader view and allows the classification of artifacts from all cycles of the software development process. The classification model of the CME distinguishes between the following concepts: • Concern space: top-level part of the model containing concerns, relationships, software artifacts, constraints, . . . ; • Concern: the traditional notion of a concern. Concerns can be specified both by a query and by an enumeration; • Concern context: specialization of a concern which relations and constraints can be attached to; • Relationship: relationships represent other concern model elements which a certain concern model element is related to. E.g. for a class C, the relationships can include all classes which refer to C, all classes which extend C, and so on; • Constraint: a constraint groups together a number of constrained elements.

برای دانلود رایگان متن کامل این مقاله و بیش از 32 میلیون مقاله دیگر ابتدا ثبت نام کنید

ثبت نام

اگر عضو سایت هستید لطفا وارد حساب کاربری خود شوید

منابع مشابه

Mining Source Code for Design Regularities

The aim of this working session on Industrial Realities of Program Comprehension is to exchange and discuss experiences, opportunities, challenges and strategies for the application of program comprehension techniques in industry. In this position paper we focus on a potentially interesting opportunity and challenge for adopting program comprehension techniques, and source code mining technique...

متن کامل

Codifying Structural Regularities of Object-Oriented Programs

Well-written object-oriented programs exhibit many structural regularities ranging from naming and coding conventions, through design patterns, to architectural constraints. Tools and environments that aid a software developer in constructing, understanding or modifying object-oriented programs should be able to reason about and manipulate such regularities. We codify structural regularities of...

متن کامل

Enforcing structural regularities in software using IntensiVE

The design and implementation of a software system is often governed by many different coding conventions, design patterns, architectural design rules, and other so-called structural regularities. To prevent a deterioration of the system’s source code, it is important that these regularities are verified and enforced in subsequent evolutions of the system. The Intensional Views Environment (Int...

متن کامل

Co-evolving code and design with intensional views: A case study

Intensional views and relations have been proposed as a way of actively documenting high-level structural regularities in the source code of a software system. By checking conformance of these intensional views and relations against the source code, they supposedly facilitate a variety of software maintenance and evolution tasks. In this paper, by performing a case study on three different vers...

متن کامل

Conceptual Code Mining Mining for Source-Code Regularities with Formal Concept Analysis

Understanding the conceptual structure of large software systems, whether it is for software understanding or reengineering purposes, is a nontrivial task. In particular, knowing where to start the comprehension process is more difficult than it seems, especially when a system is large and complex and time is scarce. We propose an approach to mine a system’s source code automatically and effici...

متن کامل

ذخیره در منابع من


  با ذخیره ی این منبع در منابع من، دسترسی به آن را برای استفاده های بعدی آسان تر کنید

عنوان ژورنال:

دوره   شماره 

صفحات  -

تاریخ انتشار 2007